package com.atguigu.gmall.rabbit.config;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.gmall.rabbit.entity.GmallCorrelationData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class RabbitMQProducerConfig implements RabbitTemplate.ConfirmCallback,RabbitTemplate.ReturnCallback, InitializingBean {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    @Qualifier("redis")
    private RedisTemplate redisTemplate;

    /**
     *
     * @param correlationData
     * @param ack
     * @param cause
     * 处理生产者投递消息到交换机所发生的情况
     */
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        if(ack){
           // log.info("消息发送成功:"+ JSON.toJSONString(correlationData));
        }else{
            //log.info("消息发送失败:"+cause+"数据:"+JSON.toJSONString(correlationData));
            this.retrySendMessage(correlationData);
        }
    }

    //重新发送消息
    private void retrySendMessage(CorrelationData correlationData){
        GmallCorrelationData gmallCorrelationData = (GmallCorrelationData) correlationData;
        int retryCount = gmallCorrelationData.getRetryCount();
        if(retryCount++<3){
            gmallCorrelationData.setRetryCount(retryCount);
            redisTemplate.opsForHash().put("rabbit:message",correlationData.getId(), JSONObject.toJSONString(gmallCorrelationData));
            //重新发送消息
            rabbitTemplate.convertAndSend(gmallCorrelationData.getExchange(),
                    gmallCorrelationData.getRoutingKey(),
                    gmallCorrelationData.getMessage(),
                    gmallCorrelationData);
        }else{
            log.info("重新发送次数用完，请管理员来处理!" +
                    JSONObject.toJSONString(gmallCorrelationData));
        }
    }
    /**
     *
     * @param message
     * @param replyCode
     * @param replyText
     * @param exchange
     * @param routingKey
     * 处理交换机通过routeKey发送给队列的情况
     */
    public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
        String uuid = (String)message.getMessageProperties().getHeader("spring_returned_message_correlation");
        String oMessage = (String)redisTemplate.opsForHash().get("rabbit:message", "uuid");
        GmallCorrelationData gmallCorrelationData = JSONObject.parseObject(oMessage, GmallCorrelationData.class);
        //重新发送
        this.retrySendMessage(gmallCorrelationData);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        this.rabbitTemplate.setConfirmCallback(this);
        this.rabbitTemplate.setReturnCallback(this);
    }
}
